//定义蛇的类
class Snake{
  //表示蛇头的元素
  head:HTMLElement
  //表示蛇身的元素(包含蛇头)
  bodies:HTMLCollection
  //表示蛇的容器
  element:HTMLElement


  constructor() {
    //获取蛇头
    this.head = document.querySelector('#snake > div') as HTMLElement
    //获取蛇容器
    this.element = document.getElementById('snake')!
    //获取到蛇身（包含蛇头）
    this.bodies = this.element.getElementsByTagName('div')

  }

  //定义获取蛇头X坐标的方法
  get X() {
    return this.head.offsetLeft
  }

  //定义获取蛇头Y坐标的方法
  get Y() {
    return this.head.offsetTop
  }

  //定义设置蛇X坐标的方法
  set X(value:number) {
    //如果修改的值与之前的值一致就不修改
    if(this.X == value) {
      return
    }
    //判断是否撞墙
    if(value < 0 || value > 290) {
      throw new Error("蛇撞墙了")
    }

    //不让蛇掉头,因为掉头的话所传入的值必须会等于第一个蛇身的坐标（蛇头后面的第一个蛇身）
    if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft == value) {
      if(value > this.X) {
        value = this.X -10
      }else {
        value = this.X + 10
      }
    }


    //蛇身移动
    this.bodymove()

    this.head.style.left = value + "px"

    //检测是否撞自己
    this.checkheadbody()
  }

  //定义设置蛇Y坐标的方法
  set Y(value:number) {
    //如果修改的值与之前的值一致就不修改
    if(this.Y == value) {
      return
    }
    //判断是否撞墙
    if(value < 0 || value > 290) {
      throw new Error("蛇撞墙了")
    }

    //不让蛇掉头,因为掉头的话所传入的值必须会等于第一个蛇身的坐标（蛇头后面的第一个蛇身）
    if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop == value) {
      if(value > this.Y) {
        value = this.Y -10
      }else {
        value = this.Y + 10
      }
    }

    //蛇身移动
    this.bodymove()

    this.head.style.top = value + "px"

    //检测是否撞自己
    this.checkheadbody()
  }

  //定义增加蛇身的方法
  addbody() {
    //beforeend是this.element的结束标签之前的位置
    this.element.insertAdjacentHTML("beforeend",'<div></div>')
  }
  //蛇身跟随移动
  bodymove() {
    //应该从最后一节开始遍历，让后一节等于前一节的坐标即可
    for(let i = this.bodies.length - 1; i > 0; i--) {
      //获取上一个的蛇身的坐标
      let beforeX:number = (this.bodies[i-1] as HTMLElement).offsetLeft;
      let beforeY:number = (this.bodies[i - 1] as HTMLElement).offsetTop;

      //设置当前元素的坐标
      (this.bodies[i] as HTMLElement).style.left = beforeX + 'px';
      (this.bodies[i] as HTMLElement).style.top  = beforeY + 'px';

    }
  }

  //判断是否撞到自己
  checkheadbody() {
    for(let i = 1; i < this.bodies.length; i++) {
      if(this.X == (this.bodies[i] as HTMLElement).offsetLeft && this.Y == (this.bodies[i] as HTMLElement).offsetTop) {
        throw new Error("撞到自己了")
      }
    }
  }
}
export default Snake
